#pragma once

#include "my_defs.h"
#include "my_rbtree.h"
#include "my_queue.h"
#include "my_log.h"
#include "my_thread_base.h"

typedef size_t (*my_slru_item_size_get_handler_t)(void *data);

typedef void (*my_slru_item_free_handler_t)(void *data);

typedef int (*my_slru_item_cmp_handler_t)(void *data_a, void *data_b);


typedef struct {
    int64_t                                 nlist;
    int64_t                                 max_item;
    int64_t                                 max_bytes;
    my_slru_item_size_get_handler_t         size_get_handler;
    my_slru_item_free_handler_t             free_handler;
    my_slru_item_cmp_handler_t              cmp_handler;

    my_queue_t                              *lists;
    int64_t                                 *lists_bytes;
    int64_t                                 *lists_n;

    my_rbtree_t                             tree;
    my_rbtree_node_t                        sentinel;
} my_slru_t;


my_slru_t *my_slru_create(
    int64_t                             nlist,
    int64_t                             max_item,
    int64_t                             max_bytes,
    my_slru_item_size_get_handler_t     size_get_handler,
    my_slru_item_free_handler_t         free_handler,
    my_slru_item_cmp_handler_t          cmp_handler);


void my_slru_destroy(my_slru_t *slru);

// if not found, return false
my_bool_t my_slru_get(my_slru_t *slru, void *target, void **data);

void my_slru_put(my_slru_t *slru, void *data);

// remove and free cache item
my_bool_t my_slru_remove(my_slru_t *slru, void *target);

// will not increase the heat of the object
my_bool_t my_slru_ge(my_slru_t *slru, void *target, void **data);

// will not increase the heat of the object
my_bool_t my_slru_le(my_slru_t *slru, void *target, void **data);